/*
 * Copyright (C) 2018 Logos Technology Ltd.
 */

package com.logos.tool;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by chenyang on 2017/6/14.
 */

public class Md5 {

    public String str;
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    /**
     * 转换md5
     *
     * @param paramArrayOfByte 字节数组
     * @param paramBoolean     是否转16进制.
     * @return MD5字符串.
     */
    public static String toMd5(byte[] paramArrayOfByte, boolean paramBoolean) {
        try {
            MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
            localMessageDigest.reset();
            localMessageDigest.update(paramArrayOfByte);
            return toHexString(localMessageDigest.digest(), "", paramBoolean);
        } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
            throw new RuntimeException(localNoSuchAlgorithmException);
        }
    }

    /**
     * 将byte转换为md5
     *
     * @param source 字节数组.
     * @return md5字符串.
     */
    public static String toMd5(byte[] source) {
        String string = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(source);
            string = toHexString(md.digest()); // 换后的结果转换为字符串
        } catch (Exception e) {
            e.fillInStackTrace();
        }
        return string;
    }

    /**
     * 将InputStream转换位md5
     *
     * @param in 输入流
     * @return md5字符串.
     */

    public static String toMd5(InputStream in) {
        String ret = null;
        if (in == null) {
            return null;
        }
        try {
            byte[] buffer = new byte[1024];
            int numRead = 0;
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            while ((numRead = in.read(buffer)) > 0) {
                md5.update(buffer, 0, numRead);
            }
            ret = toHexString(md5.digest());
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * MD5加密字符串
     *
     * @param str 需要转换的文本
     * @return md5字符串.
     */
    public static String toMd5(String str) {
        if (str == null) {
            return null;
        }

        String ret = null;
        try {
            byte[] bmsg = str.getBytes("UTF-8");
            ret = toMd5(bmsg);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * MD5加密字符串
     *
     * @param file 需要转换的文件
     * @return md5字符串.
     */
    public static String toMd5(File file) {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream in = null;
        byte[] buffer = new byte[1024];
        int len;
        try {
            digest = MessageDigest.getInstance("MD5");
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return toHexString(digest.digest());
    }

    /**
     * 转十六进制
     *
     * @param paramArrayOfByte 自己数组
     * @param paramString      需要转换文本
     * @param paramBoolean     是否转换参数.
     * @return 十六进制字符串.
     */
    public static String toHexString(byte[] paramArrayOfByte, String paramString,
                                     boolean paramBoolean) {
        StringBuilder localStringBuilder = new StringBuilder();
        for (int k : paramArrayOfByte) {
            String str = Integer.toHexString(0xFF & k);
            if (paramBoolean) {
                str = str.toUpperCase();
            }
            if (str.length() == 1) {
                localStringBuilder.append("0");
            }
            localStringBuilder.append(str).append(paramString);
        }
        return localStringBuilder.toString();
    }

    /**
     * 将byte转换为16进制
     *
     * @param bytes 字节数组
     * @return 十六进制字符串.
     */
    public static String toHexString(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            sb.append(HEX_DIGITS[(bytes[i] & 0xf0) >>> 4]);
            sb.append(HEX_DIGITS[bytes[i] & 0x0f]);
        }
        return sb.toString();
    }

    /**
     * MD5加密字符串
     *
     * @param str 需要转换的字符串
     * @return md加密后的字符串.
     */
    public static String toMd5With16bit(String str) {
        return toMd5(str).substring(8, 24);
    }
}
